package com.gmcloud.common.security.service;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ArrayUtil;
import com.gmcloud.common.core.constant.SecurityConstants;
import com.gmcloud.common.utils.R;
import com.gmcloud.common.core.utils.RetOps;
import com.gmcloud.common.security.entity.GmUser;
import com.gmcloud.upms.api.system.entity.SysRole;
import com.gmcloud.upms.api.system.entity.SysUser;
import com.gmcloud.upms.api.system.entity.dto.UserInfo;
import com.gmcloud.common.core.constant.enums.UserStatusEnum;
import org.springframework.core.Ordered;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * @author zl.sir
 * @version 1.0
 * @since 2022/8/17 16:10
 */
public interface GmUserDetailsService extends UserDetailsService, Ordered {

    /**
     * 是否支持此客户端校验
     *
     * @param clientId 目标客户端
     * @return true/false
     */
    default boolean support(String clientId, String grantType) {
        return true;
    }

    /**
     * 排序值 默认取最大的
     *
     * @return 排序值
     */
    @Override
    default int getOrder() {
        return 0;
    }

    /**
     * 构建userdetails
     *
     * @param r 用户信息
     * @return UserDetails
     */
    default UserDetails getUserDetails(R<UserInfo> r) {
        UserInfo info = RetOps.of(r).getData().orElseThrow(() -> new UsernameNotFoundException("用户不存在"));


        Set<String> dbAuthsSet = new HashSet<>();

        if (ArrayUtil.isNotEmpty(info.getRoles())) {
            // 获取角色
            Arrays.stream(info.getRoles()).forEach(role -> dbAuthsSet.add(SecurityConstants.ROLE + role));
            // 获取资源
            dbAuthsSet.addAll(Arrays.asList(info.getPermissions()));
        }

        Collection<GrantedAuthority> authorities = AuthorityUtils
                .createAuthorityList(dbAuthsSet.toArray(new String[0]));
        SysUser user = info.getSysUser();

        // 构造security用户
        GmUser gmUser = new GmUser(user.getUsername(),
                SecurityConstants.BCRYPT + user.getPassword(),
                CharSequenceUtil.equals(user.getStatus(), UserStatusEnum.STATUS_NORMAL.getType()),  // 启用
                !CharSequenceUtil.equals(user.getStatus(), UserStatusEnum.STATUS_PASSWORD_EXPIRATION.getType()), // 密码未过期
                true,  // 凭据未过期
                !CharSequenceUtil.equals(user.getStatus(), UserStatusEnum.STATUS_LOCK.getType()),  // 未锁定
                authorities);
        gmUser.setId(user.getId());
        gmUser.setPhone(user.getPhone());
        gmUser.setAdmin(user.getAdmin());
        gmUser.setEmail(user.getEmail());
        gmUser.setRoles(info.getRoleList().stream().map(SysRole::getRoleName).toList());
        gmUser.setAvatarName(user.getAvatar());
        gmUser.setNickName(user.getNickName());
        gmUser.setBirthday(user.getBirthday());
        gmUser.setGender(user.getGender());
        return gmUser;


    }

    /**
     * 通过用户实体查询
     *
     * @param gmUser user
     * @return 用户详情
     */
    default UserDetails loadUserByUser(GmUser gmUser) {
        return this.loadUserByUsername(gmUser.getUsername());
    }


}
